<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>cos-js-sdk-v5-demo</title>
    <link rel="stylesheet" href="../test/qunit-2.4.0.css">
</head>
<body>

<h1 id="qunit-header">cos-js-sdk-v5</h1>
<h2 id="qunit-banner"></h2>
<ol id="qunit-tests"></ol>

<script src="../test/qunit-2.4.0.js"></script>
<script src="../dist/cos-js-sdk-v5.js"></script>
<script>
    var config = {
        SecretId: 'xxx',
        SecretKey: 'xxx',
        Bucket: 'test-1250000000',
        Region: 'default'
    };

    var util = {
        createFile: function (options) {
            var buffer = new ArrayBuffer(options.size || 0);
            var arr = new Uint8Array(buffer);
            arr.forEach(function (char, i) {
                arr[i] = 0;
            });
            var opt = {};
            options.type && (opt.type = options.type);
            var blob = new Blob([buffer], options);
            return blob;
        },
        str2blob: function (str) {
            var size = str.length;
            var buffer = new ArrayBuffer(size || 0);
            var arr = new Uint8Array(buffer);
            arr.forEach(function (char, i) {
                arr[i] = str[i];
            });
            var blob = new Blob([buffer]);
            return blob;
        }
    };

    var cos = new COS({
        // 必选参数
        SecretId: config.SecretId,
        SecretKey: config.SecretKey,
        CompatibilityMode: true,
        ServiceDomain: 'http://cos.default.yun.ccb.com',
        Domain: 'http://{Bucket}.cos.{Region}.yun.ccb.com',
        // 可选参数
        FileParallelLimit: 3,    // 控制文件上传并发数
        ChunkParallelLimit: 3,   // 控制单个文件下分片上传并发数
        ChunkSize: 1024 * 1024,  // 控制分片大小，单位 B
        ProgressInterval: 1,  // 控制 onProgress 回调的间隔
        ChunkRetryTimes: 3,   // 控制文件切片后单片上传失败后重试次数
    });

    var AppId = config.AppId;
    var Bucket = config.Bucket;
    var BucketShortName = Bucket;
    var BucketLongName = Bucket + '-' + AppId;
    var TaskId;

    var match = config.Bucket.match(/^(.+)-(\d+)$/);
    if (match) {
        BucketLongName = config.Bucket; // Bucket 格式：test-1250000000
        BucketShortName = match[1];
        AppId = match[2];
    }

    var it = QUnit.test;
    function comparePlainObject(a, b) {
        a instanceof Array && a.sort();
        b instanceof Array && b.sort();
        if (Object.keys(a).length !== Object.keys(b).length) {
            return false;
        }
        for (var key in a) {
            if (typeof a[key] === 'object' && typeof b[key] === 'object') {
                if (!comparePlainObject(a[key], b[key])) {
                    return false;
                }
            } else if (a[key] != b[key]) {
                return false;
            }
        }
        return true;
    }

    it('getAuth()', function (assert) {
        return new Promise(function (done) {
            var content = Date.now().toString();
            var key = '1.txt';
            cos.putObject({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Key: key,
                Body: content
            }, function (err, data) {
                cos.getObjectUrl({
                    Bucket: config.Bucket,
                    Region: config.Region,
                    Key: key,
                }, function (err, data) {
                    var link = data.Url;
                    var xhr = new XMLHttpRequest();
                    xhr.open('GET', link, true);
                    data.XCosSecurityToken && xhr.setRequestHeader('x-cos-security-token', data.XCosSecurityToken);
                    xhr.onload = function (e) {
                        assert.ok(xhr.status === 200, '获取文件 200');
                        assert.ok(xhr.responseText === content, '通过获取签名能正常获取文件');
                        done();
                    };
                    xhr.onerror = function (e) {
                        assert.ok(false, '文件获取出错');
                        done();
                    };
                    xhr.send();
                });
            });
        });
    });

    it('auth check', function (assert) {
        return new Promise(function (done) {
            cos.getBucket({
                Bucket: config.Bucket,
                Region: config.Region,
                Prefix: 'aksjhdlash sajlhj!@#$%^&*()_+=-[]{}\';:"/.<>?.,??sadasd#/.,/~`',
                Headers: {
                    'x-cos-test': 'aksjhdlash sajlhj!@#$%^&*()_+=-[]{}\';:\"/.<>?.,??sadasd#/.,/~`',
                },
            }, function (err, data) {
                assert.ok(!err);
                done();
            });
        });
    });

    it('cancelTask()', function (assert) {
        return new Promise(function (done) {
            var filename = '10mb.zip';
            var blob = util.createFile({size: 1024 * 1024 * 10});
            var alive = false;
            var canceled = false;
            cos.putObject({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Key: filename,
                Body: blob,
                TaskReady: function (taskId) {
                    TaskId = taskId;
                },
                onProgress: function (info) {
                    alive = true;
                    if (!canceled) {
                        cos.cancelTask(TaskId);
                        alive = false;
                        canceled = true;
                        setTimeout(function () {
                            assert.ok(!alive, '取消上传已经生效');
                            done();
                        }, 1200);
                    }
                }
            }, function (err, data) {
                alive = true;
            });
        });
    });

    it('pauseTask(),restartTask()', function (assert) {
        return new Promise(function (done) {
            var filename = '10mb.zip';
            var blob = util.createFile({size: 1024 * 1024 * 10});
            var paused = false;
            var restarted = false;
            cos.abortUploadTask({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Key: filename,
                Level: 'file',
            }, function (err, data) {
                cos.sliceUploadFile({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    Key: filename,
                    Body: blob,
                    TaskReady: function (taskId) {
                        TaskId = taskId;
                    },
                    onProgress: function (info) {
                        if (!paused && info.percent > 0.6) {
                            cos.pauseTask(TaskId);
                            paused = true;
                            setTimeout(function () {
                                cos.restartTask(TaskId);
                                restarted = true;
                            }, 1000);
                        }
                        if (restarted) {
                            assert.ok(info.percent > 0.3, '暂停和重试成功');
                            done();
                        }
                    }
                }, function (err, data) {
                });
            });
        });
    });

    it('分片上传', function (assert) {
        return new Promise(function (done) {
            var filename = '10mb.zip';
            var blob = util.createFile({size: 1024 * 1024 * 10});
            var paused = false;
            cos.abortUploadTask({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Key: filename,
                Level: 'file',
            }, function (err, data) {
                cos.sliceUploadFile({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    Key: filename,
                    Body: blob,
                    TaskReady: function (taskId) {
                        TaskId = taskId;
                    },
                    onProgress: function (info) {
                        if (!paused && info.percent >= 0.6) {
                            paused = true;
                            cos.cancelTask(TaskId);
                            cos.sliceUploadFile({
                                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                                Region: config.Region,
                                Key: filename,
                                Body: blob,
                                TaskReady: function (taskId) {
                                    TaskId = taskId;
                                },
                                onProgress: function (info) {
                                    assert.ok(info.percent > 0.3, '分片续传成功');
                                    cos.cancelTask(TaskId);
                                    done();
                                }
                            });
                        }
                    }
                });
            });
        });
    });

    it('mock readAsBinaryString', function (assert) {
        return new Promise(function (done) {
            FileReader.prototype._readAsBinaryString = FileReader.prototype.readAsBinaryString;
            FileReader.prototype.readAsBinaryString = false;
            var filename = '10mb.zip';
            var blob = util.createFile({size: 1024 * 1024 * 10});
            var paused = false;
            cos.sliceUploadFile({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Key: filename,
                Body: blob,
                TaskReady: function (taskId) {
                    TaskId = taskId;
                },
                onProgress: function (info) {
                    if (!paused && info.percent > 0.6) {
                        cos.cancelTask(TaskId);
                        cos.sliceUploadFile({
                            Bucket: config.Bucket, // Bucket 格式：test-1250000000
                            Region: config.Region,
                            Key: filename,
                            Body: blob,
                            TaskReady: function (taskId) {
                                TaskId = taskId;
                            },
                            onProgress: function (info) {
                                assert.ok(info.percent > 0.3, '分片续传成功');
                                cos.cancelTask(TaskId);
                                FileReader.prototype.readAsBinaryString = FileReader.prototype._readAsBinaryString;
                                delete FileReader.prototype._readAsBinaryString;
                                done();
                            }
                        });
                    }
                }
            });
        });
    });


    it('abortUploadTask(),Level=task', function (assert) {
        return new Promise(function (done) {
            var filename = '10mb.zip';
            cos.multipartInit({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Key: filename,
            }, function (err, data) {
                cos.abortUploadTask({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    Key: filename,
                    Level: 'task',
                    UploadId: data.UploadId,
                }, function (err, data) {
                    var nameExist = false;
                    data.successList.forEach(function (item) {
                        if (filename === item.Key) {
                            nameExist = true;
                        }
                    });
                    assert.ok(data.successList.length >= 1, '成功取消单个分片任务');
                    assert.ok(nameExist, '成功取消单个分片任务');
                    done();
                });
            });
        });
    });

    it('abortUploadTask(),Level=file', function (assert) {
        return new Promise(function (done) {
            var filename = '10mb.zip';
            var blob = util.createFile({size: 1024 * 1024 * 10});
            cos.sliceUploadFile({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Key: filename,
                Body: blob,
                TaskReady: function (taskId) {
                    TaskId = taskId;
                },
                onProgress: function (info) {
                    cos.cancelTask(TaskId);
                    cos.abortUploadTask({
                        Bucket: config.Bucket, // Bucket 格式：test-1250000000
                        Region: config.Region,
                        Level: 'file',
                        Key: filename,
                    }, function (err, data) {
                        assert.ok(data.successList.length >= 1, '成功舍弃单个文件下的所有分片任务');
                        assert.ok(data.successList[0] && data.successList[0].Key === filename, '成功舍弃单个文件的所有分片任务');
                        done();
                    });
                }
            });
        });
    });

    it('abortUploadTask(),Level=bucket', function (assert) {
        return new Promise(function (done) {
            var filename = '10mb.zip';
            var blob = util.createFile({size: 1024 * 1024 * 10});
            cos.sliceUploadFile({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Key: filename,
                Body: blob,
                TaskReady: function (taskId) {
                    TaskId = taskId;
                },
                onProgress: function (info) {
                    cos.cancelTask(TaskId);
                    cos.abortUploadTask({
                        Bucket: config.Bucket, // Bucket 格式：test-1250000000
                        Region: config.Region,
                        Level: 'bucket',
                    }, function (err, data) {
                        var nameExist = false;
                        data.successList.forEach(function (item) {
                            if (filename === item.Key) {
                                nameExist = true;
                            }
                        });
                        assert.ok(data.successList.length >= 1, '成功舍弃Bucket下所有分片任务');
                        assert.ok(nameExist, '成功舍弃Bucket下所有分片任务');
                        done();
                    });
                }
            });
        });
    });

    it('headBucket()', function (assert) {
        return new Promise(function (done) {
            cos.headBucket({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region
            }, function (err, data) {
                assert.ok(data, '正常获取 head bucket');
                done();
            });
        });
    });

    it('headBucket() not exist', function (assert) {
        return new Promise(function (done) {
            cos.headBucket({
                Bucket: config.Bucket + Date.now().toString(36),
                Region: config.Region
            }, function (err, data) {
                assert.ok(err, 'bucket 不存在');
                done();
            });
        });
    });

    it('deleteBucket()', function (assert) {
        return new Promise(function (done) {
            cos.deleteBucket({
                Bucket: config.Bucket + Date.now().toString(36),
                Region: config.Region
            }, function (err, data) {
                assert.ok(err, '正常获取 head bucket');
                done();
            });
        });
    });

    it('getBucket()', function (assert) {
        return new Promise(function (done) {
            cos.getBucket({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region
            }, function (err, data) {
                assert.equal(true, data.Name === BucketLongName, '能列出 bucket');
                assert.equal(data.Contents.constructor, Array, '正常获取 bucket 里的文件列表');
                done();
            });
        });
    });

    it('putObject()', function (assert) {
        var filename = '1.txt';
        var getObjectETag = function (callback) {
            setTimeout(function () {
                cos.headObject({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    Key: filename,
                }, function (err, data) {
                    callback(data && data.headers && data.headers.etag);
                });
            }, 2000);
        };
        return new Promise(function (done) {
            var content = Date.now().toString();
            var lastPercent = 0;
            var blob = util.str2blob(content);
            cos.putObject({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Key: filename,
                Body: blob,
                onProgress: function (processData) {
                    lastPercent = processData.percent;
                },
            }, function (err, data) {
                if (err) throw err;
                assert.ok(data && data.ETag, 'putObject 有返回 ETag');
                getObjectETag(function (ETag) {
                    assert.ok(data.ETag === ETag, 'Blob 创建 object');
                    done();
                });
            });
        });
    });

    it('putObject(),string', function (assert) {
        var filename = '1.txt';
        return new Promise(function (done) {
            var content = '中文_' + Date.now().toString(36);
            var lastPercent = 0;
            cos.putObject({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Key: filename,
                Body: content,
                onProgress: function (processData) {
                    lastPercent = processData.percent;
                },
            }, function (err, data) {
                if (err) throw err;
                assert.ok(data && data.ETag, 'putObject 有返回 ETag');
                cos.getObject({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    Key: filename,
                }, function (err, data) {
                    assert.ok(data && data.headers && data.ETag === data.ETag && data.Body === content, '上传和下载内容一致');
                    done();
                });
            });
        });
    });

    it('putObject(),string empty', function (assert) {
        var filename = '1.txt';
        return new Promise(function (done) {
            var content = '';
            var lastPercent = 0;
            cos.putObject({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Key: filename,
                Body: content,
                onProgress: function (processData) {
                    lastPercent = processData.percent;
                },
            }, function (err, data) {
                if (err) throw err;
                assert.ok(data && data.ETag, 'putObject 有返回 ETag');
                cos.getObject({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    Key: filename,
                }, function (err, data) {
                    assert.ok(data && data.headers && data.ETag === data.ETag && data.Body === content, '上传和下载内容一致');
                    done();
                });
            });
        });
    });

    it('Key 特殊字符', function (assert) {
        return new Promise(function (done) {
            cos.putObject({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Key: '(!\'*) "#$%&+,-./0123456789:;<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~',
                Body: Date.now().toString()
            }, function (err, data) {
                if (err) throw err;
                assert.ok(data, 'putObject 特殊字符的 Key 能通过');
                done();
            });
        });
    });

    it('getObject()', function (assert) {
        return new Promise(function (done) {
            var key = '1.txt';
            var content = Date.now().toString(36);
            cos.putObject({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Key: key,
                Body: content
            }, function (err, data) {
                setTimeout(function () {
                    cos.getObject({
                        Bucket: config.Bucket, // Bucket 格式：test-1250000000
                        Region: config.Region,
                        Key: key,
                    }, function (err, data) {
                        if (err) throw err;
                        assert.ok(data.Body === content);
                        done();
                    });
                }, 2000);
            });
        });
    });

    it('putObjectCopy()', function (assert) {
        return new Promise(function (done) {
            var content = Date.now().toString(36);
            cos.putObject({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Key: '1.txt',
                Body: content,
            }, function (err, data) {
                var ETag = data.ETag;
                cos.deleteObject({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    Key: '1.copy.txt',
                }, function (err, data) {
                    cos.putObjectCopy({
                        Bucket: config.Bucket, // Bucket 格式：test-1250000000
                        Region: config.Region,
                        Key: '1.copy.txt',
                        CopySource: BucketLongName + '.cos.' + config.Region + '.yun.ccb.com/1.txt',
                    }, function (err, data) {
                        cos.headObject({
                            Bucket: config.Bucket, // Bucket 格式：test-1250000000
                            Region: config.Region,
                            Key: '1.copy.txt',
                        }, function (err, data) {
                            assert.ok(data.headers.etag === ETag, '成功复制文件');
                            done();
                        });
                    });
                });
            });
        });
    });


    it('deleteMultipleObject()', function (assert) {
        return new Promise(function (done) {
            var content = Date.now().toString(36);
            cos.putObject({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Key: '1.txt',
                Body: content,
            }, function (err, data) {
                cos.putObject({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    Key: '2.txt',
                    Body: content,
                }, function (err, data) {
                    cos.deleteMultipleObject({
                        Bucket: config.Bucket, // Bucket 格式：test-1250000000
                        Region: config.Region,
                        Objects : [
                            {Key: '1.txt'},
                            {Key: '2.txt'}
                        ],
                    }, function (err, data) {
                        assert.ok(data.Deleted.length === 2);
                        cos.headObject({
                            Bucket: config.Bucket, // Bucket 格式：test-1250000000
                            Region: config.Region,
                            Key: '1.txt',
                        }, function (err, data) {
                            assert.ok(err.statusCode === 404, '1.txt 删除成功');
                            cos.headObject({
                                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                                Region: config.Region,
                                Key: '2.txt',
                            }, function (err, data) {
                                assert.ok(err.statusCode === 404, '2.txt 删除成功');
                                done();
                            });
                        });
                    });
                });
            });
        });
    });

    it('sliceUploadFile()', function (assert) {
        return new Promise(function (done) {
            var filename = '3mb.zip';
            var blob = util.createFile({size: 1024 * 1024 * 3});
            var lastPercent = 0;
            cos.sliceUploadFile({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Key: filename,
                Body: blob,
                SliceSize: 1024 * 1024,
                AsyncLimit: 5,
                onHashProgress: function (progressData) {
                },
                onProgress: function (progressData) {
                    lastPercent = progressData.percent;
                },
            }, function (err, data) {
                assert.ok(data && data.ETag && lastPercent === 1, '上传成功');
                done();
            });
        });
    });

    (function () {
        var AccessControlPolicy = {
            "Owner": {
                "ID": 'qcs::cam::uin/10001:uin/10001' // 10001 是 QQ 号
            },
            "Grants": [{
                "Grantee": {
                    "ID": "qcs::cam::uin/10002:uin/10002", // 10002 是 QQ 号
                },
                "Permission": "READ"
            }]
        };
        var AccessControlPolicy2 = {
            "Owner": {
                "ID": 'qcs::cam::uin/10001:uin/10001' // 10001 是 QQ 号
            },
            "Grant": {
                "Grantee": {
                    "ID": "qcs::cam::uin/10002:uin/10002", // 10002 是 QQ 号
                },
                "Permission": "READ"
            }
        };
        it('putBucketAcl() header ACL:private', function (assert) {
            return new Promise(function (done) {
                cos.putBucketAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    ACL: 'private'
                }, function (err, data) {
                    assert.ok(!err, 'putBucketAcl 成功');
                    cos.getBucketAcl({
                        Bucket: config.Bucket, // Bucket 格式：test-1250000000
                        Region: config.Region
                    }, function (err, data) {
                        AccessControlPolicy.Owner.ID = data.Owner.ID;
                        AccessControlPolicy2.Owner.ID = data.Owner.ID;
                        assert.ok(data.ACL === 'private' || data.ACL === 'default');
                        done();
                    });
                });
            });
        });
        it('putBucketAcl() header ACL:public-read', function (assert) {
            return new Promise(function (done) {
                cos.putBucketAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    ACL: 'public-read',
                }, function (err, data) {
                    assert.ok(!err, 'putBucketAcl 成功');
                    cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) { // Bucket 格式：test-1250000000
                        assert.ok(data.ACL === 'public-read');
                        done();
                    });
                });
            });
        });
        it('putBucketAcl() header ACL:public-read-write', function (assert) {
            return new Promise(function (done) {
                cos.putBucketAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    ACL: 'public-read-write',
                }, function (err, data) {
                    assert.ok(!err, 'putBucketAcl 成功');
                    cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) { // Bucket 格式：test-1250000000
                        assert.ok(data.ACL === 'public-read-write');
                        done();
                    });
                });
            });
        });
        it('putBucketAcl() header GrantRead:1001,1002"', function (assert) {
            return new Promise(function (done) {
                var GrantRead = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"';
                cos.putBucketAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    GrantRead: GrantRead,
                }, function (err, data) {
                    assert.ok(!err, 'putBucketAcl 成功');
                    cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) { // Bucket 格式：test-1250000000
                        assert.ok(data.GrantRead = GrantRead);
                        done();
                    });
                });
            });
        });
        it('putBucketAcl() header GrantWrite:1001,1002', function (assert) {
            return new Promise(function (done) {
                var GrantWrite = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"';
                cos.putBucketAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    GrantWrite: GrantWrite,
                }, function (err, data) {
                    assert.ok(!err, 'putBucketAcl 成功');
                    cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) { // Bucket 格式：test-1250000000
                        assert.ok(data.GrantWrite = GrantWrite);
                        done();
                    });
                });
            });
        });
        it('putBucketAcl() header GrantFullControl:1001,1002', function (assert) {
            return new Promise(function (done) {
                var GrantFullControl = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"';
                cos.putBucketAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    GrantFullControl: GrantFullControl,
                }, function (err, data) {
                    assert.ok(!err, 'putBucketAcl 成功');
                    cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) { // Bucket 格式：test-1250000000
                        assert.ok(data.GrantFullControl = GrantFullControl);
                        done();
                    });
                });
            });
        });
        it('putBucketAcl() header ACL:public-read, GrantFullControl:1001,1002', function (assert) {
            return new Promise(function (done) {
                var GrantFullControl = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"';
                cos.putBucketAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    GrantFullControl: GrantFullControl,
                    ACL: 'public-read',
                }, function (err, data) {
                    assert.ok(!err, 'putBucketAcl 成功');
                    cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) { // Bucket 格式：test-1250000000
                        assert.ok(data.GrantFullControl = GrantFullControl);
                        assert.ok(data.ACL === 'public-read');
                        done();
                    });
                });
            });
        });
        it('putBucketAcl() xml', function (assert) {
            return new Promise(function (done) {
                cos.putBucketAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    AccessControlPolicy: AccessControlPolicy
                }, function (err, data) {
                    assert.ok(!err, 'putBucketAcl 成功');
                    cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) { // Bucket 格式：test-1250000000
                        assert.ok(data.Grants.length === 1);
                        assert.ok(data.Grants[0] && data.Grants[0].Grantee.ID === 'qcs::cam::uin/10002:uin/10002', '设置 AccessControlPolicy ID 正确');
                        assert.ok(data.Grants[0] && data.Grants[0].Permission === 'READ', '设置 AccessControlPolicy Permission 正确');
                        done();
                    });
                });
            });
        });
        it('putBucketAcl() xml2', function (assert) {
            return new Promise(function (done) {
                cos.putBucketAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    AccessControlPolicy: AccessControlPolicy2,
                }, function (err, data) {
                    assert.ok(!err, 'putBucketAcl 成功');
                    cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) { // Bucket 格式：test-1250000000
                        assert.ok(data.Grants.length === 1);
                        assert.ok(data.Grants[0] && data.Grants[0].Grantee.ID === 'qcs::cam::uin/10002:uin/10002');
                        assert.ok(data.Grants[0] && data.Grants[0].Permission === 'READ');
                        done();
                    });
                });
            });
        });
        it('putBucketAcl() decodeAcl', function (assert) {
            return new Promise(function (done) {
                cos.getBucketAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region
                }, function (err, data) {
                    cos.putBucketAcl({
                        Bucket: config.Bucket, // Bucket 格式：test-1250000000
                        Region: config.Region,
                        GrantFullControl: data.GrantFullControl,
                        GrantWrite: data.GrantWrite,
                        GrantRead: data.GrantRead,
                        ACL: data.ACL,
                    }, function (err, data) {
                        assert.ok(data);
                        done();
                    });
                });
            });
        });
    })();

    (function () {
        var AccessControlPolicy = {
            "Owner": {
                "ID": 'qcs::cam::uin/10001:uin/10001' // 10001 是 QQ 号
            },
            "Grants": [{
                "Grantee": {
                    "ID": "qcs::cam::uin/10002:uin/10002", // 10002 是 QQ 号
                },
                "Permission": "READ"
            }]
        };
        var AccessControlPolicy2 = {
            "Owner": {
                "ID": 'qcs::cam::uin/10001:uin/10001' // 10001 是 QQ 号
            },
            "Grant": {
                "Grantee": {
                    "ID": "qcs::cam::uin/10002:uin/10002", // 10002 是 QQ 号
                },
                "Permission": "READ"
            }
        };
        it('putObjectAcl() header ACL:private', function (assert) {
            return new Promise(function (done) {
                cos.putObject({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    Key: '1.txt',
                    Body: util.str2blob('hello!'),
                }, function (err, data) {
                    assert.ok(!err);
                    cos.putObjectAcl({
                        Bucket: config.Bucket, // Bucket 格式：test-1250000000
                        Region: config.Region,
                        ACL: 'private',
                        Key: '1.txt',
                    }, function (err, data) {
                        assert.ok(!err, 'putObjectAcl 成功');
                        cos.getObjectAcl({
                            Bucket: config.Bucket, // Bucket 格式：test-1250000000
                            Region: config.Region,
                            Key: '1.txt'
                        }, function (err, data) {
                            assert.ok(data.ACL = 'private');
                            AccessControlPolicy.Owner.ID = data.Owner.ID;
                            AccessControlPolicy2.Owner.ID = data.Owner.ID;
                            assert.ok(data.Grants.length === 1);
                            done();
                        });
                    });
                });
            });
        });
        it('putObjectAcl() header ACL:default', function (assert) {
            return new Promise(function (done) {
                cos.putObjectAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    ACL: 'default',
                    Key: '1.txt',
                }, function (err, data) {
                    assert.ok(!err, 'putObjectAcl 成功');
                    cos.getObjectAcl({
                        Bucket: config.Bucket, // Bucket 格式：test-1250000000
                        Region: config.Region,
                        Key: '1.txt'
                    }, function (err, data) {
                        assert.ok(data.ACL = 'default');
                        done();
                    });
                });
            });
        });
        it('putObjectAcl() header ACL:public-read', function (assert) {
            return new Promise(function (done) {
                cos.putObjectAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    ACL: 'public-read',
                    Key: '1.txt',
                }, function (err, data) {
                    assert.ok(!err, 'putObjectAcl 成功');
                    cos.getObjectAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) { // Bucket 格式：test-1250000000
                        assert.ok(data.ACL = 'public-read');
                        done();
                    });
                });
            });
        });
        it('putObjectAcl() header ACL:public-read-write', function (assert) {
            return new Promise(function (done) {
                cos.putObjectAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    ACL: 'public-read-write',
                    Key: '1.txt',
                }, function (err, data) {
                    assert.ok(!err, 'putObjectAcl 成功');
                    cos.getObjectAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) { // Bucket 格式：test-1250000000
                        assert.ok(data.ACL = 'public-read-write');
                        done();
                    });
                });
            });
        });
        it('putObjectAcl() header GrantRead:1001,1002', function (assert) {
            return new Promise(function (done) {
                var GrantRead = 'id="qcs::cam::uin/1001:uin/1001",id="qcs::cam::uin/1002:uin/1002"';
                cos.putObjectAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    GrantRead: GrantRead,
                    Key: '1.txt',
                }, function (err, data) {
                    assert.ok(!err, 'putObjectAcl 成功');
                    cos.getObjectAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) { // Bucket 格式：test-1250000000
                        assert.ok(data.GrantRead = GrantRead);
                        done();
                    });
                });
            });
        });
        it('putObjectAcl() header GrantWrite:1001,1002', function (assert) {
            return new Promise(function (done) {
                var GrantWrite = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"';
                cos.putObjectAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    GrantWrite: GrantWrite,
                    Key: '1.txt',
                }, function (err, data) {
                    assert.ok(!err, 'putObjectAcl 成功');
                    cos.getObjectAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) { // Bucket 格式：test-1250000000
                        assert.ok(data.GrantWrite = GrantWrite);
                        done();
                    });
                });
            });
        });
        it('putObjectAcl() header GrantFullControl:1001,1002', function (assert) {
            return new Promise(function (done) {
                var GrantFullControl = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"';
                cos.putObjectAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    GrantFullControl: GrantFullControl,
                    Key: '1.txt',
                }, function (err, data) {
                    assert.ok(!err, 'putObjectAcl 成功');
                    cos.getObjectAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) { // Bucket 格式：test-1250000000
                        assert.ok(data.GrantFullControl = GrantFullControl);
                        done();
                    });
                });
            });
        });
        it('putObjectAcl() header ACL:public-read, GrantRead:1001,1002', function (assert) {
            return new Promise(function (done) {
                var GrantFullControl = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"';
                cos.putObjectAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    GrantFullControl: GrantFullControl,
                    ACL: 'public-read',
                    Key: '1.txt',
                }, function (err, data) {
                    assert.ok(!err, 'putObjectAcl 成功');
                    cos.getObjectAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) { // Bucket 格式：test-1250000000
                        assert.ok(data.GrantFullControl = GrantFullControl);
                        assert.ok(data.ACL = 'public-read');
                        done();
                    });
                });
            });
        });
        it('putObjectAcl() xml', function (assert) {
            return new Promise(function (done) {
                cos.putObjectAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    AccessControlPolicy: AccessControlPolicy,
                    Key: '1.txt',
                }, function (err, data) {
                    assert.ok(!err, 'putObjectAcl 成功');
                    cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) { // Bucket 格式：test-1250000000
                        assert.ok(data.Grants.length === 1);
                        assert.ok(data.Grants[0] && data.Grants[0].Grantee.ID === 'qcs::cam::uin/10002:uin/10002', '设置 AccessControlPolicy ID 正确');
                        assert.ok(data.Grants[0] && data.Grants[0].Permission === 'READ', '设置 AccessControlPolicy Permission 正确');
                        done();
                    });
                });
            });
        });
        it('putObjectAcl() xml2', function (assert) {
            return new Promise(function (done) {
                cos.putObjectAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    AccessControlPolicy: AccessControlPolicy2,
                    Key: '1.txt',
                }, function (err, data) {
                    assert.ok(!err, 'putObjectAcl 成功');
                    cos.getObjectAcl({
                        Bucket: config.Bucket,
                        Region: config.Region,
                        Key: '1.txt'
                    }, function (err, data) { // Bucket 格式：test-1250000000
                        assert.ok(data.Grants.length === 1);
                        assert.ok(data.Grants[0] && data.Grants[0].Grantee.ID === 'qcs::cam::uin/10002:uin/10002', 'ID 正确');
                        assert.ok(data.Grants[0] && data.Grants[0].Permission === 'READ', 'Permission 正确');
                        done();
                    });
                });
            });
        });
        it('putObjectAcl() decodeAcl', function (assert) {
            return new Promise(function (done) {
                cos.getObjectAcl({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    Key: '1.txt'
                }, function (err, data) {
                    cos.putObjectAcl({
                        Bucket: config.Bucket, // Bucket 格式：test-1250000000
                        Region: config.Region,
                        Key: '1.txt',
                        GrantFullControl: data.GrantFullControl,
                        GrantWrite: data.GrantWrite,
                        GrantRead: data.GrantRead,
                        ACL: data.ACL,
                    }, function (err, data) {
                        assert.ok(data);
                        done();
                    });
                });
            });
        });
    })();

    (function () {
        var CORSRules = [{
            "AllowedOrigins": ["*"],
            "AllowedMethods": ["GET", "POST", "PUT", "DELETE", "HEAD"],
            "AllowedHeaders": ["*"],
            "ExposeHeaders": ["ETag","Content-Length"],
            "MaxAgeSeconds": "5"
        }];
        var CORSRulesMulti = [{
            "AllowedOrigins": ["*"],
            "AllowedMethods": ["GET", "POST", "PUT", "DELETE", "HEAD"],
            "AllowedHeaders": ["*"],
            "ExposeHeaders": ["ETag","Content-Length"],
            "MaxAgeSeconds": "5"
        }, {
            "AllowedOrigins": ["http://qq.com", "http://qcloud.com"],
            "AllowedMethods": ["GET", "POST", "PUT", "DELETE", "HEAD"],
            "AllowedHeaders": ["*"],
            "ExposeHeaders": ["ETag"],
            "MaxAgeSeconds": "5"
        }];
        it('putBucketCors(),getBucketCors()', function (assert) {
            return new Promise(function (done) {
                CORSRules[0].AllowedHeaders.push('test-' + Date.now().toString(36));
                cos.putBucketCors({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    CORSConfiguration: {
                        CORSRules: CORSRules
                    }
                }, function (err, data) {
                    assert.ok(!err);
                    setTimeout(function () {
                        cos.getBucketCors({
                            Bucket: config.Bucket, // Bucket 格式：test-1250000000
                            Region: config.Region
                        }, function (err, data) {

                            assert.ok(data && comparePlainObject(CORSRules, data.CORSRules));
                            done();
                        });
                    }, 2000);
                });
            });
        });
        it('putBucketCors() old', function (assert) {
            return new Promise(function (done) {
                CORSRules[0].AllowedHeaders.push('test-' + Date.now().toString(36));
                cos.putBucketCors({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    CORSConfiguration: {
                        CORSRules: CORSRules
                    }
                }, function (err, data) {
                    assert.ok(!err);
                    setTimeout(function () {
                        cos.getBucketCors({
                            Bucket: config.Bucket, // Bucket 格式：test-1250000000
                            Region: config.Region
                        }, function (err, data) {
                            assert.ok(comparePlainObject(CORSRules, data.CORSRules));
                            done();
                        });
                    }, 2000);
                });
            });
        });
        it('putBucketCors() multi', function (assert) {
            return new Promise(function (done) {
                cos.putBucketCors({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    CORSConfiguration: {
                        CORSRules: CORSRulesMulti
                    }
                }, function (err, data) {
                    assert.ok(!err);
                    setTimeout(function () {
                        cos.getBucketCors({
                            Bucket: config.Bucket, // Bucket 格式：test-1250000000
                            Region: config.Region
                        }, function (err, data) {
                            assert.ok(comparePlainObject(CORSRulesMulti, data.CORSRules));
                            done();
                        });
                    }, 2000);
                });
            });
        });
    })();

    (function () {
        var Tags = [
            {Key: "k1", Value: "v1"}
        ];
        var TagsMulti = [
            {Key: "k1", Value: "v1"},
            {Key: "k2", Value: "v2"},
        ];
        it('putBucketTagging(),getBucketTagging()', function (assert) {
            return new Promise(function (done) {
                Tags[0].Value = Date.now().toString(36);
                cos.putBucketTagging({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    Tagging: {
                        Tags: Tags
                    }
                }, function (err, data) {
                    assert.ok(!err);
                    setTimeout(function () {
                        cos.getBucketTagging({
                            Bucket: config.Bucket, // Bucket 格式：test-1250000000
                            Region: config.Region
                        }, function (err, data) {
                            assert.ok(comparePlainObject(Tags, data.Tags));
                            done();
                        });
                    }, 1000);
                });
            });
        });
        it('deleteBucketTagging()', function (assert) {
            return new Promise(function (done) {
                cos.deleteBucketTagging({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region
                }, function (err, data) {
                    assert.ok(!err);
                    setTimeout(function () {
                        cos.getBucketTagging({
                            Bucket: config.Bucket, // Bucket 格式：test-1250000000
                            Region: config.Region
                        }, function (err, data) {
                            assert.ok(comparePlainObject([], data.Tags));
                            done();
                        });
                    }, 1000);
                });
            });
        });
        it('putBucketTagging() multi', function (assert) {
            return new Promise(function (done) {
                Tags[0].Value = Date.now().toString(36);
                cos.putBucketTagging({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    Tagging: {
                        Tags: TagsMulti
                    }
                }, function (err, data) {
                    assert.ok(!err);
                    setTimeout(function () {
                        cos.getBucketTagging({
                            Bucket: config.Bucket, // Bucket 格式：test-1250000000
                            Region: config.Region
                        }, function (err, data) {
                            assert.ok(comparePlainObject(TagsMulti, data.Tags));
                            done();
                        });
                    }, 2000);
                });
            });
        });
    })();

    (function () {
        var Prefix = Date.now().toString(36);
        var Policy = {
            "version": "2.0",
            "principal": {"qcs": ["qcs::cam::uin/10001:uin/10001"]}, // 这里的 10001 是 QQ 号
            "statement": [{
                "effect": "allow",
                "action": [
                    "name/cos:GetBucket",
                    "name/cos:PutObject",
                    "name/cos:PostObject",
                    "name/cos:PutObjectCopy",
                    "name/cos:InitiateMultipartUpload",
                    "name/cos:UploadPart",
                    "name/cos:UploadPartCopy",
                    "name/cos:CompleteMultipartUpload",
                    "name/cos:AbortMultipartUpload",
                    "name/cos:AppendObject"
                ],
                "resource": ["qcs::cos:" + config.Region + ":uid/" + AppId + ":" + BucketLongName + ".cos." + config.Region + ".yun.ccb.com//" + AppId + "/" + BucketShortName + "/" + Prefix + "/*"] // 1250000000 是 appid
            }]
        };
        it('putBucketPolicy(),getBucketPolicy()', function (assert) {
            return new Promise(function (done) {
                cos.putBucketPolicy({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    Policy: Policy
                }, function (err, data) {
                    assert.ok(!err);
                    cos.getBucketPolicy({
                        Bucket: config.Bucket, // Bucket 格式：test-1250000000
                        Region: config.Region
                    }, function (err, data) {
                        assert.ok(Policy, data.Policy);
                        done();
                    });
                });
            });
        });
        it('putBucketPolicy() s3', function (assert) {
            return new Promise(function (done) {
                cos.putBucketPolicy({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    Policy: JSON.stringify(Policy)
                }, function (err, data) {
                    assert.ok(!err);
                    cos.getBucketPolicy({
                        Bucket: config.Bucket, // Bucket 格式：test-1250000000
                        Region: config.Region
                    }, function (err, data) {
                        assert.ok(Policy, data.Policy);
                        done();
                    });
                });
            });
        });
    })();

    it('getBucketLocation()', function (assert) {
        return new Promise(function (done) {
            cos.getBucketLocation({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region
            }, function (err, data) {
                var map1 = {
                    'tianjin': 'ap-beijing-1',
                    'cn-south-2': 'ap-guangzhou-2',
                    'cn-south': 'ap-guangzhou',
                    'cn-east': 'ap-shanghai',
                    'cn-southwest': 'ap-chengdu',
                };
                var map2 = {
                    'ap-beijing-1': 'tianjin',
                    'ap-guangzhou-2': 'cn-south-2',
                    'ap-guangzhou': 'cn-south',
                    'ap-shanghai': 'cn-east',
                    'ap-chengdu': 'cn-southwest',
                };
                assert.ok(data.LocationConstraint === config.Region || data.LocationConstraint === map1[config.Region] ||
                    data.LocationConstraint === map2[config.Region]);
                done();
            });
        });
    });

    (function () {
        var Rules = [{
            'ID': '1',
            'Filter': {
                'Prefix': 'test_' + Date.now().toString(36),
            },
            'Status': 'Enabled',
            'Transition': {
                'Date': '2018-07-29T16:00:00.000Z',
                'StorageClass': 'STANDARD_IA'
            }
        }];
        var RulesMulti = [{
            'ID': '1',
            'Filter': {
                'Prefix': 'test1_' + Date.now().toString(36),
            },
            'Status': 'Enabled',
            'Transition': {
                'Date': '2018-07-29T16:00:00.000Z',
                'StorageClass': 'STANDARD_IA'
            }
        }, {
            'ID': '2',
            'Filter': {
                'Prefix': 'test2_' + Date.now().toString(36),
            },
            'Status': 'Enabled',
            'Transition': {
                'Date': '2018-07-29T16:00:00.000Z',
                'StorageClass': 'STANDARD_IA'
            }
        }];
        it('deleteBucketLifecycle()', function (assert) {
            return new Promise(function (done) {
                cos.deleteBucketLifecycle({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region
                }, function (err, data) {
                    assert.ok(!err);
                    setTimeout(function () {
                        cos.getBucketLifecycle({
                            Bucket: config.Bucket, // Bucket 格式：test-1250000000
                            Region: config.Region
                        }, function (err, data) {
                            assert.ok(comparePlainObject([], data.Rules));
                            done();
                        });
                    }, 2000);
                });
            });
        });
        it('putBucketLifecycle(),getBucketLifecycle()', function (assert) {
            return new Promise(function (done) {
                Rules[0].Filter.Prefix = 'test_' + Date.now().toString(36);
                cos.putBucketLifecycle({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    LifecycleConfiguration: {
                        Rules: Rules
                    }
                }, function (err, data) {
                    assert.ok(!err);
                    setTimeout(function () {
                        cos.getBucketLifecycle({
                            Bucket: config.Bucket, // Bucket 格式：test-1250000000
                            Region: config.Region
                        }, function (err, data) {
                            assert.ok(comparePlainObject(Rules, data && data.Rules));
                            done();
                        });
                    }, 2000);
                });
            });
        });
        it('putBucketLifecycle() multi', function (assert) {
            return new Promise(function (done) {
                Rules[0].Filter.Prefix = 'test_' + Date.now().toString(36);
                cos.putBucketLifecycle({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    LifecycleConfiguration: {
                        Rules: RulesMulti
                    }
                }, function (err, data) {
                    assert.ok(!err);
                    setTimeout(function () {
                        cos.getBucketLifecycle({
                            Bucket: config.Bucket, // Bucket 格式：test-1250000000
                            Region: config.Region
                        }, function (err, data) {
                            assert.ok(comparePlainObject(RulesMulti, data.Rules));
                            done();
                        });
                    }, 2000);
                });
            });
        });
    })();

    it('params check', function (assert) {
        return new Promise(function (done) {
            cos.headBucket({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: 'gz'
            }, function (err, data) {
                assert.ok(err.error === 'error');
                done();
            });
        });
    });

    it('params check', function (assert) {
        return new Promise(function (done) {
            cos.headBucket({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: 'cos.ap-guangzhou'
            }, function (err, data) {
                assert.ok(err.error === 'param Region should not be start with "cos."');
                done();
            });
        });
    });

    it('sliceCopyFile() 正常分片复制', function (assert) {
        return new Promise(function (done) {
            var fileName = '10mb.zip';
            var Key = '10mb.copy.zip';
            var blob = util.createFile({size: 1024 * 1024 * 10});
            cos.putObject({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Key: fileName,
                Body: blob,
            }, function (err, data) {
                cos.sliceCopyFile({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    Key: Key,
                    CopySource: config.Bucket + '.cos.' + config.Region + '.yun.ccb.com/'+ fileName,
                    SliceSize: 5 * 1024 * 1024,
                    onProgress:function (processData) {
                        lastPercent = processData.percent;
                    }
                }, function (err, data) {
                    assert.ok(data && data.ETag, '成功进行分片复制');
                    done();
                });
            });
        });
    });

    it('sliceCopyFile() 单片复制', function (assert) {
        return new Promise(function (done) {
            var fileName = '10mb.zip';
            var Key = '10mb.copy.zip';
            cos.sliceCopyFile({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Key: Key,
                CopySource: config.Bucket + '.cos.' + config.Region + '.yun.ccb.com/'+ fileName,
                SliceSize: 10 * 1024 * 1024,
            }, function (err, data) {
                if (err) throw err;
                assert.ok(data && data.ETag, '成功进行单片复制');
                done();
            });
        });
    });

    (function () {
        function dataURItoBlob(dataURI) {
            var byteString = atob(dataURI.split(',')[1]);
            var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
            var ab = new ArrayBuffer(byteString.length);
            var ia = new Uint8Array(ab);
            for (var i = 0; i < byteString.length; i++) {
                ia[i] = byteString.charCodeAt(i);
            }
            return new Blob([ab], {type: mimeString});
        }
        var fileBlob = dataURItoBlob('data:text/plain;base64,5Lit5paH');
        // 这里两个用户正式测试的时候需要给 putObject 计算并加上 Content-MD5 字段
        it('putObject 带 Content-MD5 中文文件内容', function (assert) {
            return new Promise(function (done) {
                var Key = '中文.txt';
                cos.putObject({
                    Bucket: config.Bucket, // Bucket 格式：test-1250000000
                    Region: config.Region,
                    Key: Key,
                    Body: fileBlob,
                }, function (err, data) {
                    assert.ok(data && data.ETag, '成功进行上传');
                    done();
                });
            });
        });
        // it('putObject 带 Content-MD5 中文字符串', function (assert) {
        //     return new Promise(function (done) {
        //         var Key = '中文.txt';
        //         cos.putObject({
        //             Bucket: config.Bucket, // Bucket 格式：test-1250000000
        //             Region: config.Region,
        //             Key: Key,
        //             Body: fileBlob,
        //         }, function (err, data) {
        //             assert.ok(data && data.ETag, '成功进行上传');
        //             done();
        //         });
        //     });
        // });
    })();

    it('deleteMultipleObject Key 带中文字符', function (assert) {
        return new Promise(function (done) {
            cos.deleteMultipleObject({
                Bucket: config.Bucket, // Bucket 格式：test-1250000000
                Region: config.Region,
                Objects: [
                    {Key: '中文/中文.txt'},
                    {Key: '中文/中文.zip'},
                ]
            }, function (err, data) {
                assert.ok(!err, '成功进行批量删除');
                done();
            });
        });
    });
</script>

</body>
</html>